// 这个js文件用于定义验证规则
// 先引入joi模块
const joi = require('joi')
const { User, validateUser } = require('./model/user')
const { Article } = require('./model/article')
const path = require('path')
module.exports.user_add = async (req, res, next) => {
  try {
    await validateUser(req.body)
  } catch (err) {
    // 我们将错误处理统一放到错误处理中间件中去
    // return  res.redirect('/admin/user-edit?message=' + err.message)
    // 要想错误处理中间件接收 需要用next  我们还需要传入参数 但是next只能传入一个字符串参数  我们需要使用 JSON.stringify()
    // 将对象转换为字符串类型的 就可以了
    return next(
      JSON.stringify({ path: '/admin/user-edit', message: err.message })
    )
  }

  // 这里用来处理邮箱重复的问题
  let email = await User.findOne({ email: req.body.email })
  if (email !== null) {
    return next(
      JSON.stringify({ path: '/admin/user-edit', message: '邮箱重复' })
    )
  } else {
    User.create(req.body)
  }
  res.redirect('/admin/user')
  // res.send('ok')
}

module.exports.user_edit = async (req, res, next) => {
  let { id } = req.query
  let { email } = req.body
  let result = await User.findOne({ _id: id })
  // 修改信息还是 需要校验规则
  try {
    await validateUser(req.body)
  } catch (err) {
    return next(
      JSON.stringify(
        { 'path': '/admin/user-edit', 'id': id, 'message': err.message }
      )
    )
  }
  let findEmail = await User.findOne({ email: email })
  // 因为 _id 是一种特殊的对象 所以我们这里的判断最好是使用toString() 转换为字符串再进行判断  两个对象的地址是一样的 也可以直接判断的
  // 但是这里判断就是会出问题 所以还是将_id转换为字符串再判断好些
  if (findEmail !== null && findEmail._id.toString() !==
    result._id.toString()) {
    return next(
      // 这里传给错误处理中间件时 最好要把id加上 加上id才显示修改信息
      JSON.stringify(
        { 'path': '/admin/user-edit', 'id': id, 'message': '邮箱重复' })
    )
    // 校验密码是否正确 但是如果修改信息需要密码的话就无法修改密码了
  } else if (result.password !== req.body.password) {
    return next(
      JSON.stringify(
        { 'path': '/admin/user-edit', 'id': id, 'message': '密码错误' })
    )
  } else {
    if (req.app.locals.userInfo._id.toString() === result._id.toString()) {
      req.app.locals.userInfo = req.body
    }
    await User.updateOne(result, req.body)
  }
  res.redirect('/admin/user')
}

// 这里需要处理上传文件的表单 所以我们这里需要引入一个第三方模块 formidable 专门用于处理
const formidable = require('formidable')
//创建表单解析对象
const form = new formidable.IncomingForm()
// 设置上传文件的存放位置  放到uploads文件夹下
form.uploadDir = path.join(__dirname, 'public', 'uploads')
// 保留上传文件的后缀  默认不保留
form.keepExtensions = true
module.exports.article_add = async (req, res, next) => {
  // 解析表单  第一个是需要解析的表单 也就是请求 表单数据在请求中  第二个参数是一个回调函数 回调函数中第一个参数是错误信息
  // 第二个参数是对象类型普通表单数据  第三个参数是对象类型上传文件的数据  因为是异步函数 所以给一个await
  await form.parse(req, async (err, fields, files) => {
    // cover中的path字段是存放图片文件的绝对路径 我们应该只截取服务器的相对路径  所以使用这里的split可以截取相对路径
    // res.send(files.cover.path.split('public'))
    let cover = files.cover.path.split('public')[1]
    if (cover.indexOf('.') === -1) {
      // 经过测试无论有没有上传文件  files.cover.path 都不会为空  所以cover一直都有值 但是却没有意义
      // 所以这里经过判断 没有后缀名的直接不需要
      cover = ''
    }
    await Article.create({
      title: fields.title,
      writer: req.app.locals.userInfo._id,
      time: fields.time,
      content: fields.content,
      cover: cover
    })
    res.redirect('/admin/article')
  })

  // res.send('ok')
}

module.exports.article_edit = async function (req, res) {
  let { id } = req.query
  await form.parse(req, async (err, fields, files) => {
    let cover = files.cover.path.split('public')[1]
    if (cover.indexOf('.') === -1) {
      await Article.updateOne({ _id: id }, {
        title: fields.title,
        writer: req.app.locals.userInfo._id,
        time: fields.time,
        content: fields.content
      })
    } else {
      await Article.updateOne({ _id: id }, {
        title: fields.title,
        writer: req.app.locals.userInfo._id,
        time: fields.time,
        content: fields.content,
        cover: cover
      })
    }
  })
  res.redirect('/admin/article')
}

// // 定义对象的验证规则
// const schema = {
//   name: joi.string().min(2).max(10).error(new Error('错误'))
// }
//
// // 实施验证  就是validate这个函数    第一个参数是需要验证的对象  第二个参数是验证规则
// // joi.validate({ name: 'ab' }, schema)
//
// async function run () {
//   try {
//     await joi.validate({ name: 'a' }, schema)
//   } catch (err) {
//     console.log(err)
//     return
//   }
//   console.log('验证通过')
// }
//
// run()